{% extends 'base.html' %}
{% block content %}

<!-- 引入 highlight.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/github.min.css">
<!--<script src="/js/vue.js"></script>>-->
<!-- 引入 MathJax 用于渲染数学公式 -->
<script type="text/javascript" id="MathJax-script" async
  src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>
<script>
  // MathJax配置
  window.MathJax = {
    tex: {
      inlineMath: [['$', '$'], ['\\(', '\\)']],
      displayMath: [['$$', '$$'], ['\\[', '\\]']],
      processEscapes: true
    },
    options: {
      ignoreHtmlClass: 'tex2jax_ignore',
      processHtmlClass: 'tex2jax_process'
    },
    startup: {
      ready: function() {
        // 调用默认的ready函数
        MathJax.startup.defaultReady();
        
        // 在MathJax初始化完成后执行自定义处理
        setTimeout(function() {
          // 获取文章内容元素
          const contentElement = document.getElementById('content');
          if (!contentElement) return;
          
          // 获取HTML内容
          let html = contentElement.innerHTML;
          
          // 使用正则表达式查找 [ ... ] 格式的数学公式
          // 并将其转换为 \[ ... \] 格式（MathJax支持的行间公式格式）
          html = html.replace(/\[(.*?\\frac.*?)\]/g, function(match, formula) {
            // 返回替换后的格式
            return '\\[' + formula + '\\]';
          });
          
          // 更新内容
          contentElement.innerHTML = html;
          
          // 重新渲染数学公式
          MathJax.typeset([contentElement]);
        }, 500);
      }
    }
  };
</script>

<style>
    .article-detail {
        background: #fff;
        padding: 20px;
        border-radius: 5px;
        box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        margin-bottom: 20px;
    }
    .article-detail .title {
        font-size: 24px;
        font-weight: bold;
        color: #333;
        margin-bottom: 15px;
        padding-bottom: 10px;
        border-bottom: 1px solid #eee;
    }
    .article-detail .info {
        color: #666;
        font-size: 14px;
        margin-bottom: 20px;
    }
    .article-detail .content {
        color: #333;
        line-height: 1.8;
        font-size: 16px;
    }
    .article-detail .content p {
        margin-bottom: 1.2em;
    }
    .article-detail .content img {
        max-width: 100%;
        height: auto;
        margin: 10px 0;
    }
    .article-detail .content pre {
        background: #f8f9fa;
        padding: 15px;
        border-radius: 4px;
        overflow-x: auto;
        position: relative;
        margin: 1em 0;
        border: 1px solid #e1e4e8;
    }
    
    /* 代码块语言标签样式 */
    .code-language-label {
        position: absolute;
        top: 0;
        right: 0;
        padding: 0.2em 0.5em;
        font-size: 0.8em;
        background-color: #f0f0f0;
        border-left: 1px solid #ddd;
        border-bottom: 1px solid #ddd;
        border-bottom-left-radius: 4px;
        color: #666;
        font-family: monospace;
    }
    
    /* 代码样式 */
    .article-detail .content code {
        font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
        white-space: pre;
        word-spacing: normal;
        word-break: normal;
        word-wrap: normal;
        line-height: 1.5;
        tab-size: 4;
        hyphens: none;
    }
    .article-nav {
        margin: 20px 0;
        padding: 15px;
        background: #f8f9fa;
        border-radius: 4px;
    }
    .article-nav a {
        color: #007bff;
        text-decoration: none;
    }
    .article-nav a:hover {
        text-decoration: underline;
    }
    .pagination {
        margin-top: 20px;
    }
    .pagination .page-link {
        color: #007bff;
        background-color: #fff;
        border: 1px solid #dee2e6;
    }
    .pagination .page-item.active .page-link {
        background-color: #007bff;
        border-color: #007bff;
        color: #fff;
    }
    .pagination .page-item.disabled .page-link {
        color: #6c757d;
        pointer-events: none;
        background-color: #fff;
        border-color: #dee2e6;
    }
    .info {
        font-size: 14px;
        color: #666;
        line-height: 1.8;
    }
    .info .btn {
        margin-top: 10px;
        display: block;
        width: fit-content;
    }
    .favorite-link {
        display: inline-block;
        margin-left: 10px;
        vertical-align: middle;
        transition: all 0.3s ease;
    }
    .favorite-link:hover {
        transform: scale(1.05);
    }
    .favorite-link .oi {
        margin-right: 3px;
        font-size: 14px;
    }
</style>

<div class="col-sm-9 col-12" id="left" style="padding: 0;">
    <div class="col-12 row article-detail">
        <div class="col-9 title">
            {{article.headline}}
            {% if current_userid %}
                {% if current_userid == article.userid %}
                <div class="float-right">
                    <a href="/article/edit/{{article.articleid}}" class="btn btn-primary btn-sm">编辑</a>
                </div>
                {% endif %}
            {% endif %}
        </div>
        <div class="col-12 info">
            作者：{{article.nickname}}&nbsp;&nbsp;&nbsp;
            类别：{{ article_type[article.type//100] }}&nbsp;&nbsp;&nbsp;
            日期：{{article.createtime}}&nbsp;&nbsp;&nbsp;
            阅读：{{article.readcount}} 次&nbsp;&nbsp;&nbsp;
            消耗积分：{{article.credit}} 分
            &nbsp;&nbsp;&nbsp;
            {% if session.get('main_islogin') == 'true' and session.get('main_userid') == article.userid %}
                <a href="{{ url_for('article.go_edit', articleid=article.articleid) }}" >编辑</a>
            {% endif %}
            {% if session.get('main_islogin') == 'true' %}
                {% if is_favorited %}
                    <a href="javascript:void(0)" onclick="cancelFavorite({{article.articleid}})" class="favorite-link">
                        <span class="oi oi-heart" aria-hidden="true"></span>取消收藏
                    </a>
                {% else %}
                    <a href="javascript:void(0)" onclick="addFavorite({{article.articleid}})" class="favorite-link">
                        <span class="oi oi-heart" aria-hidden="true"></span>收藏文章
                    </a>
                {% endif %}
            {% endif %}

        </div>
        <div class="col-12 content" id="content" style="padding: 20px; line-height: 1.8; font-size: 16px;">
            <!-- 添加一个隐藏的div用于预处理内容 -->
            <div id="content-preprocessor" style="display:none;">{{article.content | safe}}</div>
            <!-- 实际显示的内容容器 -->
            <div id="content-display"></div>
        </div>

        <script>
            // 在页面加载完成后处理文章内容
            document.addEventListener('DOMContentLoaded', function() {
                // 获取原始内容
                var rawContent = document.getElementById('content-preprocessor').innerHTML;
                
                // 移除内联样式表代码块（通常是UEditor自动添加的）
                var cleanedContent = rawContent.replace(/<style>[\s\S]*?<\/style>/g, '');
                
                // 处理UEditor的Markdown代码块格式 (code0, code1, code2等)
                cleanedContent = processUEditorCodeBlocks(cleanedContent);
                
                // 将处理后的内容放入显示容器
                document.getElementById('content-display').innerHTML = cleanedContent;
                
                // 初始化代码高亮和其他功能
                initHighlightJS();
                
                // 如果有MathJax，重新渲染数学公式
                if (window.MathJax) {
                    MathJax.typeset(['#content-display']);
                }
            });
            
            function processUEditorCodeBlocks(content) {
                // 查找UEditor生成的代码块模式 (code0, code1, code2等)
                var codePattern = /<pre class="code(\d+)">(([\s\S](?!<\/pre>))*)<\/pre>/g;
                
                // 替换为标准的代码块格式
                return content.replace(codePattern, function(match, codeNum, codeContent) {
                    // 尝试检测代码语言
                    var language = detectCodeLanguage(codeContent);
                    
                    // 清理代码内容中的HTML实体
                    var cleanedCode = codeContent.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&');
                    
                    // 创建新的代码块，添加language-*类以便highlight.js识别
                    // 同时添加语言标识标签
                    return '<pre style="position: relative;">' +
                        '<div class="code-language-label">' + language + '</div>' +
                        '<code class="language-' + language + '">' + 
                        cleanedCode + 
                        '</code></pre>';
                });
            }
            
            // 尝试检测代码语言
            function detectCodeLanguage(code) {
                // 默认为普通文本
                var language = 'plaintext';
                
                // 简单的语言检测逻辑
                if (code.match(/^\s*(import|from|def|class|if __name__)/m)) {
                    language = 'python';
                } else if (code.match(/^\s*(function|const|let|var|import from|export|=>)/m)) {
                    language = 'javascript';
                } else if (code.match(/^\s*(public class|private|protected|void|static|@Override)/m)) {
                    language = 'java';
                } else if (code.match(/^\s*(#include|int main|std::)/m)) {
                    language = 'cpp';
                } else if (code.match(/^\s*(<html|<!DOCTYPE|<head|<body|<div|<script)/m)) {
                    language = 'html';
                } else if (code.match(/^\s*(body|margin|padding|font-size|color:|background:)/m)) {
                    language = 'css';
                } else if (code.match(/^\s*(SELECT|INSERT|UPDATE|DELETE|CREATE TABLE)/im)) {
                    language = 'sql';
                } else if (code.match(/^\s*(package|import|func|type|struct)/m)) {
                    language = 'go';
                } else if (code.match(/^\s*(\{|\[)\s*"[^"]+"\s*:/m)) {
                    language = 'json';
                }
                
                return language;
            }
        </script>

        <script>
            $(function() {
                // 获取文章内容元素
                var articleContent = $('#article-content');
                
                // 提取原始内容
                var rawContent = articleContent.html();
                
                try {
                    console.log('正在处理文章详情页内容...');
                    
                    // 检测是否包含CSS代码
                    var firstSection = rawContent.substring(0, 400); // 检查前400个字符
                    
                    // CSS关键词列表 - 包括完整和不完整片段
                    var cssKeywords = ['table', 'background', 'color', 'margin', 'padding', 'border', 'width', 'height', 
                                       'font', 'style', 'display', 'td', 'th', 'tr', 'collapse', '{', '}', 'px', 'em', 'rem',
                                       'rgb', '#', 'solid', 'dashed', 'auto', 'hidden', 'block', 'inline', 'flex',
                                       'r: 1px', 'r: 0', 'r-collapse', 'solid #', 'border-', 'order: '];
                    
                    var isCssContent = false;
                    var keywordCount = 0;
                    
                    // 判断关键词密度
                    for (var i = 0; i < cssKeywords.length; i++) {
                        if (firstSection.indexOf(cssKeywords[i]) !== -1) {
                            keywordCount++;
                            if (keywordCount >= 3) {
                                isCssContent = true;
                                break;
                            }
                        }
                    }
                    
                    // 尝试找到CSS规则模式或特殊形式的CSS代码
                    if (!isCssContent) {
                        // 判断是否有表格相关的关键词组合
                        if (firstSection.match(/(table|border)[\s-]+(collapse|width|solid|1px|\d+px|\d+%)/i)) {
                            isCssContent = true;
                        }
                        // 或者是否包含表格和表格元素的组合
                        else if (firstSection.match(/table[\s,]+(th|td|border|tr|\d+px|\d+%)/i)) {
                            isCssContent = true;
                        }
                        // 或者是否有常见的CSS规则模式
                        else if (firstSection.match(/\w+\s*{/) || firstSection.match(/\w+\s*,\s*\w+\s*{/)) {
                            isCssContent = true;
                        }
                    }
                    
                    var cleanedContent;
                    
                    if (isCssContent) {
                        console.log('文章详情页检测到CSS内容，进行处理...');
                        
                        // 确保保留完整HTML结构，但清除样式部分
                        cleanedContent = rawContent
                            // 清除所有style标签及其内容
                            .replace(/<style>[\s\S]*?<\/style>/gi, '')
                            
                            // 清除所有CSS规则
                            .replace(/[a-z0-9_.-]+\s*{[^}]*}/gi, '')
                            .replace(/[a-z0-9_.-]+\s*,[^{]*{[^}]*}/gi, '')
                            
                            // 清除各种内联CSS属性
                            .replace(/\b(style|class)="[^"]*"/gi, '')
                            .replace(/\s+style='[^']*'/gi, '')
                            
                            // 处理不完整的CSS片段
                            .replace(/r:\s*\d+px\s*[\w\s#]*;?/gi, '')
                            .replace(/r:\s*\d+px\s*solid\s*#?[\w\d]+;?/gi, '')
                            .replace(/r-[a-z]+:\s*[^;]+;?/gi, '')
                            .replace(/th,\s*th\s*{[^}]*}?/gi, '')
                            .replace(/th,\s*th/gi, '')
                            
                            // 处理残留的CSS片段
                            .replace(/\w+-(color|style|width|height|family|size|weight|align|collapse):[^;]+;?/gi, '')
                            .replace(/ackground[^;:]*:[^;]+;?/gi, '')
                            .replace(/order[^;:]*:[^;]+;?/gi, '')
                            .replace(/argin[^;:]*:[^;]+;?/gi, '')
                            .replace(/adding[^;:]*:[^;]+;?/gi, '')
                            .replace(/eight[^;:]*:[^;]+;?/gi, '')
                            .replace(/idth[^;:]*:[^;]+;?/gi, '')
                            
                            // 清理可能的残余CSS关键词以及其周围的内容
                            .replace(/\b(table|style|margin|padding|border|width|height|background|color|font)\b[^\n.]{0,20}/gi, '')
                            
                            // 移除不完整的CSS块
                            .replace(/\}[^\n\.,]{0,30}/g, '')
                            
                            // 移除所有HTML标签里的style属性
                            .replace(/(<[^>]+)\s+style\s*=\s*(['"\s])[^>]*?\2([^>]*>)/gi, '$1$3')
                            
                            // 清理额外的空白字符
                            .replace(/\s{2,}/g, ' ')
                            .trim();
                            
                        // 额外检查: 如果清理后内容还包含大量CSS关键词，进行更激进的清理
                        if (cleanedContent.match(/table|border|width|margin|padding/gi) && 
                            cleanedContent.match(/table|border|width|margin|padding/gi).length > 5) {
                            console.log('文章内容清理后仍包含CSS关键词，进行二次清理');
                            
                            // 尝试提取文章的实际内容部分 - 以第一段中文为起点
                            var contentStart = cleanedContent.search(/[\u4e00-\u9fa5]{10,}/);
                            if (contentStart > 0) {
                                cleanedContent = cleanedContent.substring(contentStart);
                            }
                            
                            // 应用最激进的清理规则
                            cleanedContent = cleanedContent
                                .replace(/table[^\u4e00-\u9fa5]{0,30}/gi, '')
                                .replace(/border[^\u4e00-\u9fa5]{0,30}/gi, '')
                                .replace(/width[^\u4e00-\u9fa5]{0,30}/gi, '')
                                .replace(/margin[^\u4e00-\u9fa5]{0,30}/gi, '')
                                .replace(/padding[^\u4e00-\u9fa5]{0,30}/gi, '')
                                .replace(/collapse[^\u4e00-\u9fa5]{0,30}/gi, '')
                                .replace(/[\{\}\;\:\#]/g, ' ')
                                .replace(/\s+/g, ' ')
                                .trim();
                        }
                    } else {
                        // 不需要特殊处理，但仍需要移除style标签和CSS规则
                        cleanedContent = rawContent
                            .replace(/<style>[\s\S]*?<\/style>/gi, '')
                            .replace(/(<[^>]+)\s+style\s*=\s*(['"\s])[^>]*?\2([^>]*>)/gi, '$1$3')
                            .replace(/tr\s*{[^}]*}/g, '')
                            .replace(/\.\w+\s*{[^}]*}/g, '')
                            .replace(/#\w+\s*{[^}]*}/g, '')
                            .replace(/[\w\s,\.#]+\{[^\}]*\}/g, '');
                    }
                    
                    // 确保页面内容仍然完整
                    if (!cleanedContent || cleanedContent.trim().length < 100) {
                        console.warn('清理后内容过短，回退到部分清理...');
                        // 仅移除style标签
                        cleanedContent = rawContent.replace(/<style>[\s\S]*?<\/style>/gi, '');
                    }
                } catch (e) {
                    // 出错时的备用处理
                    console.error('处理文章内容出错:', e);
                    cleanedContent = rawContent.replace(/<style>[\s\S]*?<\/style>/gi, '');
                }
                
                // 更新文章内容
                articleContent.html(cleanedContent);
            });
        </script>

        <!-- 只有需要消耗积分的文章且用户并未消耗过时才显示阅读全文按钮 -->
        {% if article.credit > 0 and payed == False %}
        <div class="col-12 readall" style="margin-top: 20px; text-align: center;">
            {% if session.get('islogin') == 'true' %}
            <button class="col-sm-10 col-12" onclick="readAll()">
                <span class="oi oi-data-transfer-download" aria-hidden="true"></span> 阅读全文（消耗积分：{{article['credit']}} 分）
            </button>
            {% else %}
            <button class="col-sm-10 col-12" onclick="showLogin()">
                <span class="oi oi-data-transfer-download" aria-hidden="true"></span> 你还未登录，占此登录后可阅读全文
            </button>
            {% endif %}
        </div>
        {% endif %}
    </div>

    <div class="col-12 article-nav">
        <div>版权所有，转载本站文章请注明出处：云子量化， https://www.yunjinqi.top/article/{{article.articleid}}</div>
        <div></div>
        <div><a href="/article/{{prev_next.prev_id}}">上一篇：{{prev_next.prev_headline}}</a></div>
        <div><a href="/article/{{prev_next.next_id}}">下一篇：{{prev_next.next_headline}}</a></div>
    </div>

    <!-- 文章评论 -->
    <div class="col-12 article-comment">
        <div class="col-12 row">
            <div class="col-2">
                <label for="nickname">错误反馈：</label>
            </div>
            <div class="col-10">
                <input type="text" id="nickname" class="form-control" value="本文有错误的地方可以给我发邮件指正(一个错误换一次咨询)，谢谢  yunjinqi@qq.com"  readonly>
            </div>
        </div>
        <div class="col-12 row">
            <div class="col-2">
                <label for="nickname">问题咨询：</label>
            </div>
            <div class="col-10">
                <input type="text" id="nickname" class="form-control" value="可以知乎私信我，时间精力有限，咨询可能来不及回复，见谅"  readonly>
            </div>
        </div>
        <!-- 文章总数显示 -->
        {% if total > 0 %}
        <div class="col-12" style="margin: 20px 0; text-align: center;">
            <p class="text-muted">系统当前共有 {{total}} 篇文章</p>
        </div>
        {% endif %}

    </div>
</div>

<script>
    function initHighlightJS() {
        // 扩展识别范围，包括多种常见的代码块格式
        // 1. 处理带有brush:语言的pre标签
        document.querySelectorAll('pre[class*="brush:"]').forEach((block) => {
            console.log('Processing brush block:', block);

            // 提取语言类从"brush:"前缀 (例如, brush:python -> python)
            const languageClass = block.className.match(/brush:(\S+)/);

            if (languageClass) {
                const language = languageClass[1]; // 提取出的语言，如 "python"
                
                // 添加语言类到<pre>元素
                block.classList.add(language);
                // 移除带"brush:"的部分
                block.classList.remove(`brush:${language}`);
                
                // 直接高亮<pre>标签的内容
                hljs.highlightElement(block);
            }
        });
        
        // 2. 处理带有language-*类的pre和code标签 (常见于Markdown)
        document.querySelectorAll('pre code[class*="language-"], code[class*="language-"]').forEach((block) => {
            console.log('Processing language block:', block);
            hljs.highlightElement(block);
        });
        
        // 3. 处理带有lang-*类的pre和code标签
        document.querySelectorAll('pre code[class*="lang-"], code[class*="lang-"]').forEach((block) => {
            console.log('Processing lang block:', block);
            hljs.highlightElement(block);
        });
        
        // 4. 处理UEditor生成的特殊代码块格式 (code0, code1等)
        document.querySelectorAll('pre[class*="code"]').forEach((block) => {
            console.log('Processing UEditor code block:', block);
            
            // 检查是否匹配模式 code0, code1, code2等
            const codeClassMatch = block.className.match(/code(\d+)/);
            if (codeClassMatch) {
                // 如果内部没有code标签，则创建一个
                if (!block.querySelector('code')) {
                    const codeContent = block.innerHTML;
                    const codeElement = document.createElement('code');
                    
                    // 尝试检测代码语言
                    const language = detectCodeLanguage(codeContent);
                    codeElement.className = `language-${language}`;
                    codeElement.innerHTML = codeContent;
                    
                    // 清空原来的内容并添加新的code元素
                    block.innerHTML = '';
                    block.appendChild(codeElement);
                }
                
                // 高亮代码
                const codeElement = block.querySelector('code');
                if (codeElement) {
                    hljs.highlightElement(codeElement);
                } else {
                    hljs.highlightElement(block);
                }
            }
        });
        
        // 5. 处理普通code标签，尝试自动检测语言
        document.querySelectorAll('pre > code:not([class*="language-"]):not([class*="lang-"]):not([class*="brush:"])').forEach((block) => {
            console.log('Processing plain code block:', block);
            hljs.highlightElement(block);
        });
        
        // 6. 处理直接带有编程语言名称作为类的pre或code标签
        const commonLanguages = ['python', 'javascript', 'java', 'cpp', 'csharp', 'php', 'ruby', 'go', 'rust', 'sql', 'bash', 'shell', 'html', 'css', 'json', 'xml'];
        commonLanguages.forEach(lang => {
            document.querySelectorAll(`pre.${lang}, code.${lang}`).forEach((block) => {
                console.log(`Processing ${lang} block:`, block);
                hljs.highlightElement(block);
            });
        });
    }
    // Initialize highlight.js when the page is loaded
    document.addEventListener('DOMContentLoaded', function () {
        initHighlightJS(); // Call the function to initialize syntax highlighting
    });


    // 如果文章内容是动态加载的（例如通过 AJAX），在加载完成后重新初始化
    function readAll() {
        let param = 'articleid={{article.articleid}}&position={{position}}';
        $.post('/readall', param, function (data) {
            $("#content").append(data);
            $(".readall").hide();
            initHighlightJS(); // 重新初始化 highlight.js
        });
    }

    // 其他函数（如 addFavorite、cancelFavorite 等）
    function addFavorite(articleid) {
    // 缓存选择器
    let $favoriteBtn = $(".favorite-link");

    $.post('/favorite', 'articleid=' + articleid, function (data) {
        if (data === 'not-login') {
            bootbox.alert({ title: "错误提示", message: "你还没有登录，不能收藏文章." });
        }
        else if (data === 'favorite-pass') {
            bootbox.alert({ title: "信息提示", message: "文章收藏成功，可在我的收藏中查看." });
            $favoriteBtn.html('<span class="oi oi-heart" aria-hidden="true"></span> 感谢收藏');
            $favoriteBtn.attr('onclick', '').unbind('click');
        }
        else {
            bootbox.alert({ title: "错误提示", message: "收藏文章出错，请联系管理员." });
        }
    });
    }

    function cancelFavorite(articleid) {
        // 缓存选择器
        let $favoriteBtn = $(".favorite-link");

        $.ajax({
            url: '/favorite/' + articleid,
            type: 'delete',
            success: function (data) {
                if (data === 'not-login') {
                    bootbox.alert({title: "错误提示", message: "你还没有登录，不能取消收藏文章."});
                }
                else if (data === 'cancel-pass') {
                    bootbox.alert({title: "信息提示", message: "取消收藏成功."});
                    $favoriteBtn.html('<span class="oi oi-heart" aria-hidden="true"></span> 欢迎再来');
                    $favoriteBtn.attr('onclick', '').unbind('click');
                }
                else if (data === 'cancel-fail') {
                    bootbox.alert({title: "错误提示", message: "取消收藏出错，请联系管理员."});
                }
            }
        });
    }

    // Vue for comments
    let v = new Vue({
        el: '#commentDiv',
        delimiters: ['${', '}'],
        data: {commentList: []}
    });

    function fillComment(articleid, pageid) {
        $.get('/comment/' + articleid + '-' + pageid, function (data) {
            v.commentList = data;
        });
    }

    window.onload = function () {
        fillComment('{{article.articleid}}', '1');
    };
</script>

{% include 'side.html' %}

{% endblock %}
